package com.demo.webflux.spring5core.framework.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

import com.demo.webflux.spring5core.framework.aop.intercept.MethodInvocation;
import com.demo.webflux.spring5core.framework.aop.support.AdvisedSupport;

import feign.Feign;

public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {

	private AdvisedSupport config;

	public JdkDynamicAopProxy(AdvisedSupport config) {
		this.config = config;
	}

	// 把原生对象传进来
	@Override
	public Object getProxy() {
		return getProxy(config.getTargetClass().getClassLoader());
	}

	@Override
	public Object getProxy(ClassLoader classLoader) {
		return Proxy.newProxyInstance(classLoader, config.getTargetClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		String key = Feign.configKey(config.getTargetClass(), method);
		// 将每一个JointPoint也就是被代理的业务方法(Method)封装成一个拦截器，组合成一个拦截器链
		List<Object> interceptorsAndDynamicMethodMatchers = config.getInterceptorsAndDynamicInterceptionAdvice(key, config.getTargetClass());
		// 交给拦截器链MethodInvocation的process方法执行
		MethodInvocation invocation = new MethodInvocation(proxy, config.getTarget(), method, args, config.getTargetClass(), interceptorsAndDynamicMethodMatchers);
		return invocation.process();
	}

}
